package org.example.travel_web.service.impl;

import jakarta.annotation.Resource;
import org.example.travel_web.dto.data.*;
import org.example.travel_web.enums.Type;
import org.example.travel_web.mapper.AttractionsMapper;
import org.example.travel_web.mapper.DataMapper;
import org.example.travel_web.mapper.NewsMapper;
import org.example.travel_web.mapper.RoutesMapper;
import org.example.travel_web.service.DataService;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DataServiceImpl implements DataService {
    @Resource
    private NewsMapper newsMapper;
    @Resource
    private AttractionsMapper attractionsMapper;
    @Resource
    private RoutesMapper routesMapper;
    @Resource
    private DataMapper dataMapper;

    @Override
    public List<NewsRankResp> getNewsRank() {
        return newsMapper.getNewsRank();
    }

    @Override
    public List<RouteRankResp> getRouteRank() {
        return routesMapper.getRouteRank();
    }

    @Override
    public List<AttractionRankResp> getAttractionRank() {
        return attractionsMapper.getAttractionRank();
    }

    @Override
    public List<CommentRankResp> getCommentRank() {
        List<CommentRankResp> rank = dataMapper.getCommentRank();
        for (CommentRankResp item : rank) {
            item.setTitle(getTitle(item.getType(), item.getRelateId()));
        }
        return rank;
    }

    @Override
    public List<CollectRankResp> getCollectRank() {
        List<CollectRankResp> rank = dataMapper.getCollectRank();
        for (CollectRankResp item : rank) {
            item.setTitle(getTitle(item.getType(), item.getRelateId()));
        }
        return rank;
    }

    @Override
    public LineChartDataResp getLineChartData() {
        LocalDate today = LocalDate.now();
        LocalDateTime end = LocalDateTime.of(today, LocalTime.MIN);
        LocalDateTime start = end.minusDays(7);
        List<String> xAsis = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            xAsis.add(start.plusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        LineChartDataResp.LineChartDataRespBuilder builder = LineChartDataResp.builder();
        builder.xAxis(xAsis);
        List<LineGraphDataItem> commentSeries = dataMapper.getCommentByDateRange(start, end);
        List<LineGraphDataItem> collectSeries = dataMapper.getCollectByDateRange(start, end);
        builder.series(List.of(getFinalMap(xAsis, commentSeries, "评论数量"),
                getFinalMap(xAsis, collectSeries, "收藏数量")));
        return builder.build();
    }

    @Override
    public TotalDataResp getTotalData() {
        return TotalDataResp.builder()
                .userCount(dataMapper.getUserCount())
                .todayUserCount(dataMapper.getTodayUserCount(LocalDateTime.of(LocalDate.now(), LocalTime.MIN)))
                .totalResource(dataMapper.getTotalResource())
                .totalComment(dataMapper.getTotalComment())
                .build();
    }

    private Map<String, Object> getFinalMap(List<String> xAsis, List<LineGraphDataItem> series, String name) {
        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("type", "line");
        List<Integer> finalData = new ArrayList<>();
        for (String date : xAsis) {
            series.stream().filter(item -> item.getSingleDay().toString().equals(date))
                    .findFirst()
                    .ifPresentOrElse(item -> finalData.add(item.getCount()), () -> finalData.add(0));
        }
        map.put("data", finalData);
        return map;
    }

    private String getTitle(Type type, Integer relateId) {
        switch (type) {
            case ATTRACTION -> {
                return attractionsMapper.selectById(relateId).getName();
            }
            case NEWS -> {
                return newsMapper.selectById(relateId).getTitle();
            }
            case ROUTE -> {
                return routesMapper.selectById(relateId).getTitle();
            }
            default -> {
                return "";
            }
        }
    }
}
